local H = require "packages/new_heg/util"
local U = require "packages/utility/utility"
local extension = Package:new("flow")
extension.extensionName = "hegemony_diy"
extension.game_modes_whitelist = { 'nos_heg_mode', 'new_heg_mode' }

Fk:loadTranslationTable{
  ["flow"] = "日月交辉·流",
  ["wk_heg"] = "日月",
  ["hegemony_diy"] = "国战扩展",
}

local liuye = General(extension, "wk_heg__liuye", "wei", 3)
local poyuan = fk.CreateTriggerSkill{
  name = "wk_heg__poyuan",
  anim_type = "offensive",
  events = {fk.Damage, fk.DamageCaused},
  can_trigger = function (self, event, target, player, data)
    if not (target == player and player:hasSkill(self) and player:isAlive()) then return false end
    if event == fk.Damage then
      return data.to ~= player and not data.to.dead and #data.to:getCardIds("e") > 0
    else
      if not (H.isBigKingdomPlayer(data.to) and player.room.current == player) then return false end
      local events = player.room.logic:getActualDamageEvents(1, function(e)
        return e.data[1].from == player and H.isBigKingdomPlayer(e.data[1].to)
      end, Player.HistoryTurn)
      return #events == 0 and player:getMark("wk_heg__poyuan-turn") == 0
    end
  end,
  on_cost = function (self, event, target, player, data)
    if event == fk.Damage then
      return player.room:askForSkillInvoke(player, self.name, nil, "#wk_heg__poyuan-discard")
    else
      return true
    end
  end,
  on_use = function (self, event, target, player, data)
    local room = player.room
    if event == fk.Damage then
      local id = room:askForCardChosen(player, data.to, "e", self.name)
      room:throwCard(id, self.name, data.to, player)
    else
      data.damage = data.damage + 1
      room:setPlayerMark(player, "wk_heg__poyuan-turn", 1)
    end
  end,
}

local choulue = fk.CreateTriggerSkill{
  name = "wk_heg__choulue",
  anim_type = "offensive",
  events = {fk.Damaged, fk.TargetSpecified},
  can_trigger = function (self, event, target, player, data)
    if event == fk.Damaged then
      return player == target and player:hasSkill(self) and player:getMark("@!yinyangfish") < player.maxHp
    else
      return player:hasSkill(self) and H.compareKingdomWith(player, target) and #AimGroup:getAllTargets(data.tos) == 1
        and data.card:isCommonTrick() and player:getMark("@!yinyangfish") ~= 0
    end
  end,
  on_cost = function (self, event, target, player, data)
    return player.room:askForSkillInvoke(player, self.name, nil, event == fk.Damaged and "#wk_heg__choulue-getfish" or "#wk_heg__choulue-twice")
  end,
  on_use = function (self, event, target, player, data)
    local room = player.room
    if event == fk.Damaged then
      H.addHegMark(room, player, "yinyangfish")
    else
      room:removePlayerMark(player, "@!yinyangfish")
      if player:getMark("@!yinyangfish") == 0 then
        player:loseFakeSkill("yinyangfish_skill&")
      end
      data.additionalEffect = 1
    end
  end,
}

liuye:addSkill(poyuan)
liuye:addSkill(choulue)
Fk:loadTranslationTable{
  ["wk_heg__liuye"] = "刘晔",
  ["#wk_heg__liuye"] = "画策谁迎",
  ["designer:wk_heg__liuye"] = "教父&卧雏",

  ["wk_heg__poyuan"] = "破垣",
  [":wk_heg__poyuan"] = "①当你对其他角色造成伤害后，你可弃置其一张装备区内的牌；②当你于回合内首次对大势力角色造成伤害时，此伤害+1。",
  ["wk_heg__choulue"] = "筹略",
  [":wk_heg__choulue"] = "①当你受到伤害后，若你的“阴阳鱼”标记数小于你体力上限，你可获得一个“阴阳鱼”标记；②当与你势力相同的角色使用普通锦囊牌指定唯一目标后，你可移去一个“阴阳鱼”标记，令此牌结算两次。",

  ["#wk_heg__poyuan-discard"] = "破垣：是否弃置受伤角色装备区内一张牌",
  ["poyuan_discard-hand"] = "令其弃置一张手牌",
  ["poyuan_discard-equip"] = "弃置其一张装备区内的牌",

  ["#wk_heg__choulue-getfish"] = "筹略：是否获得一个“阴阳鱼”标记",
  ["#wk_heg__choulue-twice"] = "筹略：是否移去一个“阴阳鱼”标记，令此牌结算两次",

  ["$wk_heg__poyuan1"] = "砲石飞空，坚垣难存。",
  ["$wk_heg__poyuan2"] = "声若霹雳，人马俱摧。",
  ["$wk_heg__choulue1"] = "筹画所料，无有不中。",
  ["$wk_heg__choulue2"] = "献策破敌，所谋皆应。",
  ["~wk_heg__liuye"] = "功名富贵，到头来，不过黄土一抔…",
}

local huanfan = General(extension, "wk_heg__huanfan", "wei", 3)
local liance_viewas = fk.CreateViewAsSkill{
  name = "#wk_heg__liance_viewas",
  interaction = function()
    local names = {}
    local mark = Self:getMark("wk_heg__liance-phase")
    for _, id in ipairs(Fk:getAllCardIds()) do
      local card = Fk:getCardById(id, true)
      if table.contains(mark, card.name) and card:isCommonTrick() then
        table.insertIfNeed(names, card.name)
      end
    end
    return UI.ComboBox {choices = names}
  end,
  card_filter = Util.FalseFunc,
  view_as = function(self, cards)
    if not self.interaction.data then return end
    local card = Fk:cloneCard(self.interaction.data)
    return card
  end,
}
local liance = fk.CreateTriggerSkill{
  name = "wk_heg__liance",
  anim_type = "offensive",
  events = {fk.EventPhaseEnd},
  can_trigger = function(self, event, target, player, data)
    if not (player:hasSkill(self) and target.phase == Player.Play and player ~= target and not player:isNude()) then return false end
    local usedCardNames = {}
    return #player.room.logic:getEventsOfScope(GameEvent.UseCard, 1, function(e)
      local use = e.data[1]
      if table.contains(usedCardNames, e.data[1].card.name) then
        return use.from == target.id and use.card:isCommonTrick()
      else
        if use.from == target.id and use.card:isCommonTrick() then
          table.insert(usedCardNames, e.data[1].card.name)
        end
        return false
      end
    end, Player.HistoryPhase) > 0
  end,
  on_cost = function(self, event, target, player, data)
    local cards = player.room:askForDiscard(player, 1, 1, true, self.name, true, ".", "#wk_heg__liance-invoke::"..target.id, true)
    if #cards == 1 then
      self.cost_data = cards
      return true
    end
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    local usedCardNames = {}
    room:throwCard(self.cost_data, self.name, player, player)
    local events = player.room.logic:getEventsOfScope(GameEvent.UseCard, 998, function(e)
      local use = e.data[1]
      if table.contains(usedCardNames, e.data[1].card.name) then
        return use.from == target.id and use.card.type == Card.TypeTrick
      else
        if use.from == target.id and use.card.type == Card.TypeTrick then
          table.insert(usedCardNames, e.data[1].card.name)
        end
        return false
      end
    end, Player.HistoryPhase)
    local usedCardTwice = {}
    table.forEach(events, function(e)
      table.insertIfNeed(usedCardTwice, e.data[1].card.name)
    end)

    room:setPlayerMark(target, "wk_heg__liance-phase", usedCardTwice)
    local success, dat = player.room:askForUseActiveSkill(target, "#wk_heg__liance_viewas", "#wk_heg__liance-choose", true)
    -- if not success then
    --   H.askCommandTo(player, target, self.name, true)
    -- else
    if success then
      local card = Fk.skills["#wk_heg__liance_viewas"]:viewAs(usedCardTwice.cards)
      room:useCard{
        from = target.id,
        tos = table.map(dat.targets, function(id) return {id} end),
        card = card,
      }
    end
  end,
}

local shilun_active = fk.CreateActiveSkill{
  name = "#wk_heg__shilun_active",
  can_use = Util.FalseFunc,
  target_num = 0,
  card_num = function()
    local cards = Self.player_cards[Player.Hand]
    local suits = {}
    for _, id in ipairs(cards) do
      local suit = Fk:getCardById(id).suit
      if suit ~= Card.NoSuit then
        if not table.contains(suits, suit) then
          table.insert(suits, suit)
        end
      end
    end
    return #suits
  end,
  card_filter = function(self, to_select, selected)
    if Fk:currentRoom():getCardArea(to_select) == Player.Equip then return end
    return table.every(selected, function (id) return Fk:getCardById(to_select).suit ~= Fk:getCardById(id).suit end)
  end,
}

local shilun = fk.CreateTriggerSkill{
  name = "wk_heg__shilun",
  events = {fk.Damaged},
  anim_type = "defensive",
  can_trigger = function(self, event, target, player, data)
    return player == target and player:hasSkill(self) and not player:isKongcheng()
  end,
  on_use = function (self, event, target, player, data)
    local room = player.room
    local cards = player.player_cards[Player.Hand]
    player:showCards(cards)
    local _, ret = room:askForUseActiveSkill(player, "#wk_heg__shilun_active", "#wk_heg__shilun_active-choose", false)
    local to_remain
    if ret then
      to_remain = ret.cards
    end
    local cards = table.filter(player:getCardIds{Player.Hand}, function (id)
      return not (table.contains(to_remain, id) or player:prohibitDiscard(Fk:getCardById(id)))
    end)
    if #cards > 0 then
      room:throwCard(cards, self.name, player)
    end
    local cards = player.player_cards[Player.Hand]
    if #cards == 4 then
      if #room:canMoveCardInBoard() > 0 then
        local targets = room:askForChooseToMoveCardInBoard(player, "#wk_heg__shilun-move", self.name, true, nil)
        if #targets ~= 0 then
          targets = table.map(targets, function(id) return room:getPlayerById(id) end)
          room:askForMoveCardInBoard(player, targets[1], targets[2], self.name)
        end
      end
    else
      local suits = {Card.Spade, Card.Heart, Card.Diamond, Card.Club}
      for _, id in ipairs(cards) do
        local suit = Fk:getCardById(id).suit
        if suit ~= Card.NoSuit then
          table.removeOne(suits, suit)
        end
      end
      local patternTable = { ["heart"] = {}, ["diamond"] = {}, ["spade"] = {}, ["club"] = {} }
      for _, id in ipairs(room.draw_pile) do
        local card = Fk:getCardById(id)
        if table.contains(suits, card.suit) then
          table.insert(patternTable[card:getSuitString()], id)
        end
      end
      local get = {}
      for _, ids in pairs(patternTable) do
        if #ids > 0 then
          table.insert(get, table.random(ids))
        end
      end
      if #get > 0 then
        room:obtainCard(player, get, false, fk.ReasonPrey)
      end
    end
  end,
}

huanfan:addSkill(liance)
huanfan:addSkill(shilun)
Fk:addSkill(liance_viewas)
Fk:addSkill(shilun_active)
Fk:loadTranslationTable{
  ["wk_heg__huanfan"] = "桓范",
  ["#wk_heg__huanfan"] = "雍国立世",
  ["designer:wk_heg__huanfan"] = "教父",

  ["wk_heg__liance"] = "连策",
  [":wk_heg__liance"] = "其他角色的出牌阶段结束时，若其于此阶段内使用过同名普通锦囊牌，你可弃置一张牌，令其选择是否视为使用此回合内其使用过的其中一张同名牌。",
  ["wk_heg__shilun"] = "世论",
  [":wk_heg__shilun"] = "当你受到伤害后，你可展示所有手牌并弃至每种花色各一张，然后若你的手牌：包含四种花色，你可移动场上一张牌；不包含四种花色，你从牌堆中检索并获得手牌中没有的花色牌各一张。",

  ["#wk_heg__liance-invoke"] = "连策：你可以弃置一张牌，令 %dest 视为使用锦囊牌",
  ["#wk_heg__liance-choose"] = "连策：选择你要使用的牌",
  ["#wk_heg__shilun_active-choose"] = "世论：选择花色各不相同的手牌各一张",
  ["#wk_heg__shilun-move"] = "世论：你可以移动场上一张牌",
  ["#wk_heg__liance_viewas"] = "连策",
  ["#wk_heg__shilun_active"] = "世论",

  ["$wk_heg__liance1"] = "将军今出洛阳，恐难再回。",
  ["$wk_heg__liance2"] = "贼示弱于外，必包藏祸心。",
  ["$wk_heg__shilun1"] = "某有良谋，可为将军所用。",
  ["$wk_heg__shilun2"] = "吾负十斗之囊，其盈一石之智。",
  ["~wk_heg__huanfan"] = "有良言而不用，君何愚哉……",
}

local wenpin = General(extension, "wk_heg__wenpin", "wei", 4, 4, General.Male)
local zhenwei = fk.CreateTriggerSkill{
  name = "wk_heg__zhenwei",
  anim_type = "defensive",
  frequency = Skill.Limited,
  events = {fk.EventPhaseStart},
  can_trigger = function (self, event, target, player, data)
    return player:hasSkill(self) and player:usedSkillTimes(self.name, Player.HistoryGame) == 0 and player ~= target and target.phase == Player.Play
  end,
  on_use = function (self, event, target, player, data)
    local room = player.room
    local targets = table.map(table.filter(room:getOtherPlayers(player), function(p)
      return p ~= room.current and p:getMark("@@lure_tiger-turn") == 0 end), function(p) return p.id end)
    local tos = room:askForChoosePlayers(player, targets, 1, 2, "#wk_heg__zhenwei-choose")
    room:useVirtualCard("lure_tiger", nil, player, table.map(tos, function(id) return room:getPlayerById(id) end), self.name)
    -- if #tos > 0 then
    --   for _, pid in ipairs(tos) do
    --     local target = room:getPlayerById(pid)
    --     room:setPlayerMark(target, "@@lure_tiger-turn", 1)
    --     room:setPlayerMark(target, MarkEnum.PlayerRemoved .. "-turn", 1)
    --     room:handleAddLoseSkills(target, "#lure_tiger_hp|#lure_tiger_prohibit", nil, false, true) -- global...
    --     room.logic:trigger("fk.RemoveStateChanged", target, nil) -- FIXME
    --   end
    -- end
  end,
}
local zhenwei_delay = fk.CreateTriggerSkill{
  name = "#wk_heg__zhenwei_delay",
  visible = false,
  frequency = Skill.Compulsory,
  events = {fk.TurnEnd},
  mute = true,
  can_trigger = function(self, event, target, player, data)
    if player:usedSkillTimes(zhenwei.name, Player.HistoryTurn) == 0 then return false end 
    local targets = {}
    player.room.logic:getActualDamageEvents(1, function(e)
      local damage = e.data[1]
      if player == damage.to then
        table.insertIfNeed(targets, damage.to.id)
      end
      return false
    end)
    return #targets == 0
  end,
  on_use = function(self, event, target, player, data)
    player:setSkillUseHistory("wk_heg__zhenwei", 0, Player.HistoryGame)
  end,
}

local yulin = H.CreateArraySummonSkill{
  name = "wk_heg__yulin",
  array_type = "siege",
}
local yulinTrigger = fk.CreateTriggerSkill{
  name = "#wk_heg__yulin_trigger",
  visible = false,
  frequency = Skill.Compulsory,
  events = {fk.Damage},
  can_trigger = function(self, event, target, player, data)
    return H.hasShownSkill(player, self) and data.card and data.card.trueName == "slash" and H.inSiegeRelation(target, player, data.to) 
      and #player.room.alive_players > 3 and U.damageByCardEffect(player.room) and player:hasShownSkill(yulin)
  end,
  on_use = function(self, event, target, player, data)
    player.room:recover({
      who = target,
      num = 1,
      recoverBy = player,
      skillName = self.name,
    })
  end
}

yulin:addRelatedSkill(yulinTrigger)
zhenwei:addRelatedSkill(zhenwei_delay)
wenpin:addSkill(zhenwei)
wenpin:addSkill(yulin)
Fk:loadTranslationTable{
  ["wk_heg__wenpin"] = "文聘",
  ["#wk_heg__wenpin"] = "坚城宿将",
  ["designer:wk_heg__wenpin"] = "紫乔&教父",

  ["wk_heg__zhenwei"] = "镇卫",
  [":wk_heg__zhenwei"] = "限定技，其他角色的出牌阶段开始时，你可视为对至多两名除你与其的角色使用【调虎离山】，且此回合结束时，若你于此回合内未受到过伤害，你复原此技能。",
  ["wk_heg__yulin"] = "鱼鳞",
  [":wk_heg__yulin"] = "阵法技，若你是围攻角色，此围攻关系中的围攻角色使用【杀】对被围攻角色造成伤害后，其回复1点体力。<br />"..
    "<font color = 'gray'>注：阵法技来源于紫星居设计-文聘，已取得紫乔授权。",

  ["#wk_heg__zhenwei-choose"] = "镇卫：你可以对至多两名你与当前回合外的角色视为使用【调虎离山】",
  ["#wk_heg__yulin_trigger"] = "鱼鳞",

  ["$wk_heg__zhenwei1"] = "再敢来犯，定叫你无功而返！",
  ["$wk_heg__zhenwei2"] = "江夏防线，固若金汤。",
  ["~wk_heg__wenpin"] = "终于...也守不住了",
}

local dongyun = General(extension, "wk_heg__dongyun", "shu", 3, 3, General.Male)
local yizan = fk.CreateTriggerSkill{
  name = "wk_heg__yizan",
  anim_type = "drawcard",
  events = {fk.EventPhaseStart},
  can_trigger = function (self, event, target, player, data)
    return player:hasSkill(self) and player.phase == Player.Discard
  end,
  on_cost = function (self, event, target, player, data)
    local room = player.room
    if event == fk.EventPhaseStart then
      if player.room:askForSkillInvoke(player, self.name, nil, "#wk_heg__yizan-invoke") then
        local targets = table.map(table.filter(room:getOtherPlayers(player), function(p)
          return (p:getHandcardNum() < player:getHandcardNum()) end), function(p) return p.id end)
        if #targets > 0 then
          local to = room:askForChoosePlayers(player, targets, 1, 1, "#wk_heg__yizan-choose", self.name, true)
          self.cost_data = to[1]
          if #to > 0 then
            return true
          end
        end
      end
    end
  end,
  on_use = function (self, event, target, player, data)
    local room = player.room
    local to = room:getPlayerById(self.cost_data)
    to:drawCards(math.min(player:getHandcardNum() - #to.player_cards[Player.Hand], 5), self.name)
    room:setPlayerMark(player, "wk_heg__yizan-phase", self.cost_data)
  end,
}

local yizan_delay = fk.CreateTriggerSkill{
  name = "#wk_heg__yizan_delay",
  anim_type = "special",
  events = {fk.EventPhaseEnd},
  can_trigger = function (self, event, target, player, data)
    if not (player:hasSkill(self) and player.phase == Player.Discard and player:getMark("wk_heg__yizan-phase") ~= 0) then return false end 
    local logic = player.room.logic
    local x = 0
    logic:getEventsOfScope(GameEvent.MoveCards, 1, function (e)
      for _, move in ipairs(e.data) do
        if move.from == player.id and move.moveReason == fk.ReasonDiscard and move.skillName == "phase_discard" then
          x = x + #move.moveInfo
          if x > 1 then return true end
        end
      end
      return false
    end, Player.HistoryTurn)
    return x > 0
  end,
  on_cost = Util.TrueFunc,
  on_use = function (self, event, target, player, data)
    local room = player.room
    local to = room:getPlayerById(player:getMark("wk_heg__yizan-phase"))
    local throw_num = #to.player_cards[Player.Hand] - to.maxHp
    if throw_num > 0 then
      room:askForDiscard(to, throw_num, throw_num, false, self.name, false)
    end
  end,
}

local juanshe = fk.CreateTriggerSkill{
  name = "wk_heg__juanshe",
  anim_type = "recover",
  events = {fk.EventPhaseStart},
  can_trigger = function (self, event, target, player, data)
    -- local current = player.room.current
    local events = target.room.logic:getEventsOfScope(GameEvent.UseCard, 999, function(e) 
      local use = e.data[1]
      return use.from == target.id 
    end, Player.HistoryTurn)
    return #events < target:getMaxCards() and H.compareKingdomWith(player, target) 
      and target.phase == Player.Finish and player:hasSkill(self) and not target:isKongcheng()
  end,
  on_cost = function (self, event, target, player, data)
    return player.room:askForSkillInvoke(player, self.name, nil, "#wk_heg__juanshe-invoke")
  end,
  on_use = function (self, event, target, player, data)
    local room = player.room
    room:askForDiscard(target, 1, 1, false, self.name, false)
    if target:isWounded() then
      room:recover({
        who = target,
        num = 1,
        recoverBy = player,
        skillName = self.name,
      })
    end
    room:setPlayerMark(target, "@@wk_heg__juanshe-prohibit", 1)
  end,

  refresh_events = {fk.EventPhaseChanging, fk.BuryVictim, fk.Damaged},
  can_refresh = function(self, event, target, player, data)
    if event == fk.EventPhaseChanging then
      return player.room.current:getMark("@@wk_heg__juanshe-prohibit") > 0 and data.from == Player.NotActive
    elseif event == fk.BuryVictim or event == fk.Damaged then
      return player == target and player:hasSkill(self)
    end
  end,
  on_refresh = function(self, event, target, player, data)
    if event == fk.EventPhaseChanging then
      player.room:setPlayerMark(player.room.current, "@@wk_heg__juanshe-prohibit", 0)
    elseif event == fk.BuryVictim or event == fk.Damaged then
      for _, p in ipairs(player.room.alive_players) do
        if p:getMark("@@wk_heg__juanshe-prohibit") > 0 then
          player.room:setPlayerMark(p, "@@wk_heg__juanshe-prohibit", 0)
        end
      end
    end
  end,
}

local juanshe_prohibit = fk.CreateProhibitSkill{
  name = "#wk_heg__juanshe_prohibit",
  prohibit_use = function(self, player, card)
    if player:getMark("@@wk_heg__juanshe-prohibit") == 0 then return false end 
    local subcards = Card:getIdList(card)
    return #subcards > 0 and table.every(subcards, function(id)
      return table.contains(player:getCardIds(Player.Hand), id)
    end)
  end,
}

dongyun:addCompanions("ld__jiangwanfeiyi")
yizan:addRelatedSkill(yizan_delay)
juanshe:addRelatedSkill(juanshe_prohibit)
dongyun:addSkill(yizan)
dongyun:addSkill(juanshe)
Fk:loadTranslationTable{
  ["wk_heg__dongyun"] = "董允",
  ["#wk_heg__dongyun"] = "匡主正堂",
  ["designer:wk_heg__dongyun"] = "教父&修功&风箫",

  ["wk_heg__yizan"] = "翼赞",
  [":wk_heg__yizan"] = "弃牌阶段开始时，你可令一名手牌数小于你的角色将手牌摸至与你相同（至多摸五张），然后此阶段结束时，若你于此阶段内弃置过牌，其将手牌弃至体力上限。",
  ["wk_heg__juanshe"] = "蠲奢",
  [":wk_heg__juanshe"] = "与你势力相同角色的结束阶段，若其本回合使用牌数小于其手牌上限，你可令其弃置一张手牌并回复1点体力，然后直至其回合开始或你受到伤害，其不能使用手牌。",

  ["@@wk_heg__juanshe-prohibit"] = "蠲奢 禁用手牌",

  ["#wk_heg__yizan_delay"] = "翼赞",
  ["#wk_heg__yizan-invoke"] = "翼赞：是否令一名手牌数小于你的角色将手牌摸至与你相同",
  ["#wk_heg__yizan-choose"] = "翼赞：选择一名手牌数小于你的角色，令其将手牌摸至与你相同",
  ["#wk_heg__juanshe-invoke"] = "蠲奢：是否令当前回合角色弃置一张手牌，然后其回复1点体力",

  ["$wk_heg__yizan1"] = "公事为重，宴席不去也罢。",
  ["$wk_heg__yizan2"] = "还是改日吧。",
  ["$wk_heg__juanshe1"] = "自古，就是邪不胜正！。",
  ["$wk_heg__juanshe2"] = "主公面前，岂容小人搬弄是非。",
  ["~wk_heg__dongyun"] = "大汉，要亡于宦官之手了…",
}

local hudu = General(extension, "wk_heg__hudu", "shu", 4, 4, General.Male)
local fuman = fk.CreateActiveSkill{
  name = "wk_heg__fuman",
  anim_type = "control",
  card_num = 1,
  target_num = 1,
  prompt = "#wk_heg__fuman",
  can_use = function(self, player)
    return player:usedSkillTimes(self.name, Player.HistoryPhase) == 0 and not player:isKongcheng()
  end,
  card_filter = function(self, to_select, selected)
    return #selected == 0 and Fk:currentRoom():getCardArea(to_select) == Player.Hand
  end,
  target_filter = function(self, to_select, selected)
    return #selected == 0 and to_select ~= Self.id
  end,
  on_use = function(self, room, effect)
    local player = room:getPlayerById(effect.from)
    local target = room:getPlayerById(effect.tos[1])
    if player.dead or not table.contains(player:getCardIds("h"), effect.cards[1]) then return end
    local card = Fk:getCardById(effect.cards[1])
    player:showCards(card)
    room:obtainCard(target, card, true, fk.ReasonGive)
    if player.dead or target.dead then return end
    local cards2 = target:getCardIds("he")
    local choices = {}
    if #cards2 > 1 then
      local num = #table.filter(target:getCardIds("he"), function(id) return Fk:getCardById(id).color == card.color end)
      if num > 1 then
        table.insert(choices, "wk_heg__fuman-give")
      end
    end
    local slash_card = Fk:cloneCard("slash")
    slash_card.skillName = self.name
    if U.canUseCardTo(room, target, player, slash_card, false, false) and not target:prohibitUse(slash_card) then
      table.insert(choices, "wk_heg__fuman-useslash")
    end
    if #choices == 0 then return end
    local choice = room:askForChoice(target, choices, self.name)
    if choice == "wk_heg__fuman-useslash" then
      local use = room:useVirtualCard("slash", nil, target, player, self.name, true)
      room:damage{
        from = player,
        to = target,
        damage = 1,
        skillName = self.name,
      }
    else
      local cards3 
      if card.color == Card.Red then
        cards3 = room:askForCard(target, 2, 2, true, self.name, false, ".|.|heart,diamond|.|.|.", "#wk_heg__fuman-give1:"..player.id)
      elseif card.color == Card.Black then
        cards3 = room:askForCard(target, 2, 2, true, self.name, false, ".|.|club,spade|.|.|.", "#wk_heg__fuman-give2:"..player.id)
      end
      room:moveCardTo(cards3, Player.Hand, player, fk.ReasonGive, self.name, nil, false, player.id)
    end
  end, 
}

local fuwei = fk.CreateTriggerSkill{
  name = "wk_heg__fuwei",
  anim_type = "support",
  events = {"fk.GeneralRemoving", fk.EnterDying},
  can_trigger = function (self, event, target, player, data)
    if event == fk.EnterDying then 
      return player:hasSkill(self) and H.compareKingdomWith(player, target)
      and #table.filter(target.player_skills, function(s)
        return s.frequency == Skill.Limited and target:usedSkillTimes(s.name, Player.HistoryGame) > 0
      end) > 0
    else
      return player:hasSkill(self) and H.compareKingdomWith(player, target)
    end
  end,
  on_use = function (self, event, target, player, data)
    local room = player.room
    if event == "fk.GeneralRemoving" then
      room:loseHp(player, 1, self.name)
      H.transformGeneral(room, target, not data)
      return true
    else
      local skillNames = table.map(table.filter(target.player_skills, function(s)
        return s.frequency == Skill.Limited and target:usedSkillTimes(s.name, Player.HistoryGame) > 0
      end), Util.NameMapper)
      local skill = room:askForChoice(player, skillNames, self.name, "#wk_heg__fuwei-reset::"..target.id)
      target:addSkillUseHistory(skill, -1)
      player:throwAllCards("h")
      room:handleAddLoseSkills(player, "-wk_heg__fuwei", nil)
    end
  end,
}

hudu:addSkill(fuman)
hudu:addSkill(fuwei)
Fk:loadTranslationTable{
  ["wk_heg__hudu"] = "马忠",
  ["#wk_heg__hudu"] = "雍国立世",
  ["designer:wk_heg__hudu"] = "二四",

  ["wk_heg__fuman"] = "抚蛮",
  [":wk_heg__fuman"] = "出牌阶段限一次，你可展示并交给一名其他角色一张手牌，然后其选择一项：1.交给你两张与此牌颜色相同的牌；2.视为对你使用一张【杀】，然后你对其造成1点伤害。",
  ["wk_heg__fuwei"] = "扶危",
  [":wk_heg__fuwei"] = "与你势力相同的角色：1.移除武将牌时，你可失去1点体力，令此次移除操作改为变更对应的武将牌；2.进入濒死状态时，你可令其武将牌上一个已发动过的限定技的发动次数+1，然后你弃置所有手牌并失去此技能。",

  ["#wk_heg__fuman"] = "抚蛮：交给一名其他角色一张牌",

  ["wk_heg__fuman-give"] = "交给牌",
  ["wk_heg__fuman-useslash"] = "视为使用【杀】",
  ["#wk_heg__fuman-give1"] = "交给 %src 两张红色牌",
  ["#wk_heg__fuman-give2"] = "交给 %src 两张黑色牌",
  ["#wk_heg__fuwei-reset"] = "扶危：选择 %src 一个已发动过的限定技，令此技能视为未发动过",
  ["#wk_heg__fuman_trigger"] = "抚蛮",

  ["$wk_heg__fuman1"] = "国家兴亡，匹夫有责。",
  ["$wk_heg__fuman2"] = "跟着我们丞相走，错不了。",
  ["$wk_heg__fuwei1"] = "改狐为马，若川中老骥，镇守南疆。",
  ["$wk_heg__fuwei2"] = "更笃为忠，报先帝之恩，忠贞辅国。",
  ["~wk_heg__hudu"] = "南征不定，后患无穷…",
}

local yangyi = General(extension, "wk_heg__yangyi", "shu", 3, 3, General.Male)
local juanxia = fk.CreateTriggerSkill{
  name = "wk_heg__juanxia",
  anim_type = "offensive",
  events = {fk.EventPhaseStart},
  can_trigger = function (self, event, target, player, data)
    return player:hasSkill(self) and target == player and player.phase == Player.Finish and U.canUseCard(player.room, player, Fk:cloneCard("slash"))
  end,
  on_cost = function (self, event, target, player, data)
    local room = player.room
    local targets = {}
    local slash = Fk:cloneCard("slash")
    for _, p in ipairs(room:getOtherPlayers(player)) do
      if not player:isProhibited(p, slash) then
        table.insert(targets, p.id)
      end
    end
    local tos = room:askForChoosePlayers(player, targets, 1, 1, "#wk_heg__juanxia-choose", self.name, true)
    if #tos > 0 then
      self.cost_data = tos[1]
      return true
    end
  end,
  on_use = function (self, event, target, player, data)
    local room = player.room
    local to = room:getPlayerById(self.cost_data)
    room:useVirtualCard("slash", nil, player, to, self.name, true)
    local choices = {"start_command", "Cancel"}
    if not to.dead and room:askForChoice(to, choices, self.name) == "start_command" and not H.askCommandTo(to, player, self.name) then
      room:damage{
        from = to,
        to = player,
        damage = 1,
        skillName = self.name,
      }
    end
  end,
}

--- 交换主副将
---@param room Room
---@param player ServerPlayer
---@return boolean
local function SwapMainAndDeputy(room, player)
  local general1 = player.general
  local general2 = player.deputyGeneral
  if not (general1 and general2) then return false end
  if general1 == "anjiang" then player:revealGeneral(false, true) end
  if general2 == "anjiang" then player:revealGeneral(true, true) end
  general1 = player.general
  general2 = player.deputyGeneral
  if string.find(general1, "lord") 
   or string.find(general1, "zhonghui") or string.find(general1, "simazhao") 
   or string.find(general1, "sunchen") or string.find(general1, "gongsunyuan") 
  then return false end
  room:changeHero(player, "blank_shibing", false, true, false, false, false)
  room:changeHero(player, general2, false, false, true, false, false)
  room:changeHero(player, general1, false, true, true, false, false)
  return true
end

local fenduan = fk.CreateTriggerSkill{
  name = "wk_heg__fenduan",
  anim_type = "offensive",
  relate_to_place = "m",
  events = {"fk.ChooseDoCommand", "fk.AfterCommandUse"},
  can_trigger = function (self, event, target, player, data)
    return player:hasSkill(self) and target == player and (event == "fk.AfterCommandUse" or not player.chained)
  end,
  on_cost = function (self, event, target, player, data)
    if event == "fk.ChooseDoCommand" then
      return player.room:askForSkillInvoke(player, self.name, nil, "#wk_heg__fenduan-invoke")
    else
      return true
    end
  end,
  on_use = function (self, event, target, player, data)
    local room = player.room
    if event == "fk.ChooseDoCommand" then
      player:setChainState(true)
      return true
    else
      room:askForDiscard(data.from, 2, 2, false, self.name, false)
      SwapMainAndDeputy(room, player)
    end
  end,
}

local choucuo = fk.CreateTriggerSkill{
  name = "wk_heg__choucuo",
  anim_type = "drawcard",
  relate_to_place = "d",
  events = {fk.EventPhaseStart},
  can_trigger = function (self, event, target, player, data)
    return player == target and player:hasSkill(self) and player.phase == Player.Play
  end,
  on_use = function (self, event, target, player, data)
    local room = player.room
    local cards = player:drawCards(2)
    player:showCards(cards)
    if not player.dead then
      local mark = {}
      for _, id in ipairs(cards) do
        if room:getCardArea(id) == Card.PlayerHand and room:getCardOwner(id) == player then
          table.insert(mark, id)
          room:setCardMark(Fk:getCardById(id), "@@wk_heg__choucuo_inhand-phase", 1)
        end
      end
      room:setPlayerMark(player, "wk_heg__choucuo-phase", mark)
    end
  end,

  refresh_events = {fk.AfterCardsMove},
  can_refresh = function(self, event, target, player, data)
    if type(player:getMark("wk_heg__choucuo-phase")) ~= "table" then return false end
    local mark = player:getMark("wk_heg__choucuo-phase")
    local toLose = {}
    for _, move in ipairs(data) do
      if move.from == player.id then
        for _, info in ipairs(move.moveInfo) do
          if info.fromArea == Card.PlayerHand and table.contains(mark, info.cardId) then
            table.insert(toLose, info.cardId)
          end
        end
      end
    end
    if #toLose > 0 then
      self.cost_data = toLose
      return true
    end
  end,
  on_refresh = function(self, event, target, player, data)
    local mark = player:getMark("wk_heg__choucuo-phase")
    table.forEach(self.cost_data, function(id) table.removeOne(mark, id) end)
    player.room:setPlayerMark(player, "wk_heg__choucuo-phase", #mark > 0 and mark or 0)
  end,
}
local choucuo_delay = fk.CreateTriggerSkill{
  name = "#wk_heg__choucuo_delay",
  mute = true,
  events = {fk.EventPhaseEnd},
  can_trigger = function (self, event, target, player, data)
    return player:usedSkillTimes(choucuo.name, Player.HistoryPhase) > 0 and player.phase == Player.Play and #player.room.logic:getEventsOfScope(GameEvent.UseCard, 998, function(e)
      local use = e.data[1]
      return use.from == player.id
    end, Player.HistoryPhase) >= player.hp
  end,
  on_cost = Util.TrueFunc,
  on_use = function (self, event, target, player, data)
    local room = player.room
    room:notifySkillInvoked(player, choucuo.name, "special")
    player:broadcastSkillInvoke(choucuo.name)
    SwapMainAndDeputy(room, player)
  end,
}
choucuo:addRelatedSkill(choucuo_delay)
local choucuo_prohibit = fk.CreateProhibitSkill{
  name = "#wk_heg__choucuo_prohibit",
  prohibit_use = function(self, player, card)
    if player:getMark("wk_heg__choucuo-phase") == 0 then return false end
    local cards = card:isVirtual() and card.subcards or {card.id}
    return table.find(cards, function(id) return Fk:getCardById(id):getMark("@@wk_heg__choucuo_inhand-phase") == 0 end)
  end,
}
choucuo:addRelatedSkill(choucuo_prohibit)
yangyi:addSkill(juanxia)
yangyi:addSkill(fenduan)
yangyi:addSkill(choucuo)
Fk:loadTranslationTable{
  ["wk_heg__yangyi"] = "杨仪",
  ["#wk_heg__yangyi"] = "狷恙逆跋",
  ["designer:wk_heg__yangyi"] = "教父",

  ["wk_heg__juanxia"] = "狷狭",
  [":wk_heg__juanxia"] = "结束阶段，你可选择一名其他角色，视为对其使用一张【杀】，然后若其存活，其可对你发起“军令”，若你不执行，其对你造成1点伤害。",
  ["wk_heg__fenduan"] = "忿断",
  [":wk_heg__fenduan"] = "主将技，当你选择执行“军令”时，若你未横置，你可改为横置；当你成为“军令”的目标结算完成后，你令此“军令”的发起者弃置两张手牌，然后你交换主副将。",
  ["wk_heg__choucuo"] = "筹措",
  [":wk_heg__choucuo"] = "副将技，出牌阶段开始时，你可摸两张牌并展示之，若如此做，你不能使用其它牌直至你失去这些牌或此阶段结束，且此阶段结束时，若你于此阶段内使用的牌数不小于体力值，你交换主副将。",

  ["#wk_heg__juanxia-choose"] = "狷狭：你可选择一名其他角色，视为对其使用一张【杀】",

  ["#wk_heg__fenduan-invoke"] = "忿断：是否将此次执行的军令改为横置",

  ["#wk_heg__choucuo_delay"] = "筹措",
  ["@@wk_heg__choucuo_inhand-phase"] = "筹措",

  ["$wk_heg__juanxia1"] = "汝有何功，竟能居我之上！",
  ["$wk_heg__juanxia2"] = "恃才傲立，恩怨必偿。",
  ["$wk_heg__fenduan1"] = "北伐之事，丞相亦听我定夺。",
  ["$wk_heg__fenduan2"] = "早知如此，投靠魏国又如何！",
  ["$wk_heg__choucuo1"] = "丞相新丧，吾当继之。",
  ["$wk_heg__choucuo2"] = "规划分部，筹度粮谷。",
  ["~wk_heg__yangyi"] = "魏延庸奴，吾，誓杀汝！",
}

local luotong = General(extension, "wk_heg__luotong", "wu", 3)
local mingzheng = fk.CreateTriggerSkill{
  name = "wk_heg__mingzheng",
  anim_type = "drawcard",
  events = {fk.GeneralRevealed, fk.EventPhaseStart},
  can_trigger = function (self, event, target, player, data)
    if not (player:hasSkill(self) and H.compareKingdomWith(target, player) and not target.dead) then return false end
    if event == fk.GeneralRevealed then
      return H.getGeneralsRevealedNum(target) == 2
    else
      return target.phase == Player.Play
    end
  end,
  on_cost = Util.TrueFunc,
  on_use = function (self, event, target, player, data)
    local room = player.room
    if event == fk.EventPhaseStart then
      local targets = table.map(table.filter(room.alive_players, function(p) return H.compareKingdomWith(p, player) and p ~= target end), Util.IdMapper)
      if #targets > 0 then
        local to = room:askForChoosePlayers(target, targets, 1, 1, "#wk_heg__mingzheng-choose", self.name, false)
        local p = room:getPlayerById(to[1])
        room:askForCardsChosen(target, p, 0, 0, {
          card_data = {
            { "$Hand", p:getCardIds(Player.Hand) }
          }
        }, self.name, "wk_heg__mingzheng-hand::"..to[1])
      end
    end
    if event == fk.GeneralRevealed then
      target:reset()
      room:addPlayerMark(target, "@!yinyangfish", 1)
      target:addFakeSkill("yinyangfish_skill&")
      target:prelightSkill("yinyangfish_skill&", true)
    end
  end,
}

local yujian = fk.CreateTriggerSkill{
  name = "wk_heg__yujian",
  anim_type = "control",
  events = {fk.Damage},
  can_trigger = function (self, event, target, player, data)
    if not (player:hasSkill(self) and target ~= player and data.from.phase == Player.Play and H.compareKingdomWith(player, data.to)) then return false end
    local events = player.room.logic:getActualDamageEvents(2, function(e)
      return H.compareKingdomWith(e.data[1].to, player) and data.from == player.room.current and data.from and data.from.phase == Player.Play
    end, Player.HistoryTurn)
    return #events == 1
  end,
  on_use = function (self, event, target, player, data)
    local room = player.room
    local current = room.current
    if target.hp <= player.hp then
      U.swapHandCards(room, player, player, current, self.name)
      room:setPlayerMark(player, "@@wk_heg__yujian_exchange-turn", 1)
    end
    if H.getGeneralsRevealedNum(target) == 2 and room:askForChoice(player, {"wk_heg__yujian_hide::" .. target.id, "Cancel"}, self.name) ~= "Cancel" then
      for _, p in ipairs({target}) do
        local isDeputy = H.doHideGeneral(room, player, p, self.name)
        room:setPlayerMark(p, "@wk_heg__yujian_reveal-turn", H.getActualGeneral(p, isDeputy))
        local record = type(p:getMark(MarkEnum.RevealProhibited .. "-turn")) == "table" and p:getMark(MarkEnum.RevealProhibited .. "-turn") or {}
        table.insert(record, isDeputy and "d" or "m")
        room:setPlayerMark(p, MarkEnum.RevealProhibited .. "-turn", record)
      end
    end
  end,
}

local yujian_delay = fk.CreateTriggerSkill{
  name = "#wk_heg__yujian_delay",
  anim_type = "special",
  events = {fk.TurnEnd},
  can_trigger = function (self, event, target, player, data)
    return player:getMark("@@wk_heg__yujian_exchange-turn") > 0 and not player.dead and not player.room.current.deat
  end,
  on_cost = Util.TrueFunc,
  on_use = function (self, event, target, player, data)
    local room = player.room
    local current = room.current
    U.swapHandCards(room, player, player, current, self.name)
  end
}

yujian:addRelatedSkill(yujian_delay)
luotong:addSkill(mingzheng)
luotong:addSkill(yujian)
Fk:loadTranslationTable{
  ["wk_heg__luotong"] = "骆统",
  ["#wk_heg__luotong"] = "达弼政辅",
  ["designer:wk_heg__luotong"] = "教父",

  ["wk_heg__mingzheng"] = "明政",
  [":wk_heg__mingzheng"] = "与你势力相同的角色：1.明置武将牌后，若其武将牌均明置，其复原武将牌，然后获得一个“阴阳鱼”标记; 2.出牌阶段开始时，其观看除其外一名与你势力相同的角色的手牌。",
  ["wk_heg__yujian"] = "御谏",
  [":wk_heg__yujian"] = "其他角色于其出牌阶段内首次对与你势力相同的角色造成伤害后，你可依次执行每个满足条件的项：1.若其体力值不大于你，你可与其交换手牌，若如此做，此回合结束时，你与其交换手牌；"..
  "2.若其武将牌均明置，你可暗置其一张武将牌且直至本回合结束不能明置之。",

  ["#wk_heg__mingzheng-choose"] = "明政：选择一名与你势力相同的其他角色观看手牌",
  ["wk_heg__mingzheng-hand"] = "明政：观看%dest的手牌",
  ["wk_heg__yujian_hide"] = "暗置%dest一张武将牌且本回合不能明置",

  ["#wk_heg__yujian_delay"] = "御谏",
  ["@@wk_heg__yujian_exchange-turn"] = "御谏 交换手牌",
  ["@wk_heg__yujian_reveal-turn"] = "御谏 禁亮",

  ["$wk_heg__mingzheng1"] = "仁政如水，可润万物",
  ["$wk_heg__mingzheng2"] = "为官一任，当造福一方",
  ["$wk_heg__yujian1"] = "臣代天子牧民，闻苛自当谏之。",
  ["$wk_heg__yujian2"] = "为将者死战，为臣者死谏。",
  ["~wk_heg__luotong"] = "而立之年，奈何早逝。",
}

local zhuran = General(extension, "wk_heg__zhuran", "wu", 4, 4, General.Male)
local danshou = fk.CreateTriggerSkill{
  name = "wk_heg__danshou",
  events = {fk.TargetConfirmed},
  anim_type = "defensive",
  can_trigger = function(self, event, target, player, data)
    if player:hasSkill(self) and target == player and data.from ~= player.id and player:usedSkillTimes(self.name, Player.HistoryTurn) == 0 then
      local events = player.room.logic:getEventsOfScope(GameEvent.UseCard, 999, function(e)
        local use = e.data[1]
        return table.contains(TargetGroup:getRealTargets(use.tos), player.id)
      end, Player.HistoryTurn)
      self.cost_data = #events
      return true
    end
  end,
  on_cost = function(self, event, target, player, data)
    local n = player:getHandcardNum() - self.cost_data
    if n > 0 then
      local cards = player.room:askForDiscard(player, n, n, false, self.name, true, ".", "#wk_heg__danshou-damage::"..data.from..":"..n, true)
      if #cards == n then
        self.cost_data = {n, cards}
        return true
      end
    else
      self.cost_data = {n}
      return player.room:askForSkillInvoke(player, self.name, nil, "#wk_heg__danshou:::"..-n)
    end
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    if self.cost_data[1] > 0 then
      local to = room:getPlayerById(data.from)
      room:doIndicate(player.id, {data.from})
      room:throwCard(self.cost_data[2], self.name, player, player)
      if not to.dead then 
        room:damage{
          from = player,
          to = to,
          damage = 1,
          skillName = self.name,
        }
      end
    else
      player:drawCards(-self.cost_data[1], self.name)
    end
  end,
}

zhuran:addCompanions("hs__lvmeng")
zhuran:addSkill(danshou)
Fk:loadTranslationTable{
  ["wk_heg__zhuran"] = "朱然",
  ["#wk_heg__zhuran"] = "胆略无双",
  ["designer:wk_heg__zhuran"] = "教父&二四",

  ["wk_heg__danshou"] = "胆守",
  [":wk_heg__danshou"] = "每回合限一次，当你成为其他角色使用牌的目标后，你可将手牌调整至X张，若你因此法失去牌，你对其造成1点伤害（X为你本回合成为过牌目标的次数）。",

  ["#wk_heg__danshou-damage"] = "胆守：你可以弃置 %arg 张牌，对 %dest 造成1点伤害",
  ["#wk_heg__danshou"] = "胆守：你可以摸 %arg 张牌",

  ["$wk_heg__danshou1"] = "到此为止了！",
  ["$wk_heg__danshou2"] = "以胆为守，扼敌咽喉！",
  ["~wk_heg__zhuran"] = "何人竟有如此之胆！？",
}

local sunshao = General(extension, "wk_heg__sunshao", "wu", 3, 3, General.Male)

local wk_heg__zhiheng = fk.CreateActiveSkill{
  name = "wk_heg__zhiheng",
  anim_type = "drawcard",
  can_use = function(self, player)
    return player:usedSkillTimes(self.name, Player.HistoryPhase) == 0
  end,
  target_num = 0,
  min_card_num = 1,
  max_card_num = function()
    return table.find(Self:getEquipments(Card.SubtypeTreasure), function(cid)
      return Fk:getCardById(cid).name == "luminous_pearl"
    end) and 998 or Self.maxHp
  end,
  card_filter = function(self, to_select, selected)
    if #selected >= Self.maxHp then
      return table.find(Self:getEquipments(Card.SubtypeTreasure), function(cid)
        return Fk:getCardById(cid).name == "luminous_pearl" and not table.contains(selected, cid) and to_select ~= cid
      end)
    end
    return #selected < Self.maxHp and not Self:prohibitDiscard(Fk:getCardById(to_select))
  end,
  on_use = function(self, room, effect)
    local from = room:getPlayerById(effect.from)
    room:throwCard(effect.cards, self.name, from, from)
    if not from.dead then
      from:drawCards(#effect.cards, self.name)
    end
  end
}

local function getTrueSkills(player)
  local skills = {}
  for _, s in ipairs(Fk.generals[player.general]:getSkillNameList()) do
    table.insertIfNeed(skills, s)
  end
  for _, s in ipairs(Fk.generals[player.deputyGeneral]:getSkillNameList()) do
    table.insertIfNeed(skills, s)
  end
  return skills
end

local bizheng = fk.CreateTriggerSkill{
  name = "wk_heg__bizheng",
  anim_type = "special",
  events = {fk.AfterCardsMove},
  can_trigger = function(self, event, target, player, data)
    if player:hasSkill(self) and player:usedSkillTimes(self.name, Player.HistoryTurn) == 0 and player.room.current.phase == Player.Play then
      local room = player.room
      local current = room.current
      local cards = {}
      for _, move in ipairs(data) do
        if move.moveReason == fk.ReasonDiscard and move.toArea == Card.DiscardPile and move.from and move.from == current.id and not room:getPlayerById(move.from).dead then
          for _, info in ipairs(move.moveInfo) do
            if info.fromArea == Card.PlayerHand or info.fromArea == Card.PlayerEquip then
              table.insert(cards, info.cardId)
              cards = U.moveCardsHoldingAreaCheck(room, cards)
            end
          end
        end
      end
      if #cards > 0 then
        self.cost_data = cards
        return true
      end
    end
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    room:moveCards{
      ids = self.cost_data,
      to = player.id,
      toArea = Card.PlayerHand,
      moveReason = fk.ReasonJustMove,
      proposer = player.id,
      skillName = self.name,
    }
    local card = player:getCardIds("he")
    local skills = #getTrueSkills(room.current)
    if #card > skills then
      card = room:askForCard(player, skills, skills, true, self.name, false)
    end
    if #card == 0 then return end
    if #card > 1 then
      card = room:askForGuanxing(player, card, nil, {0, 0}, self.name, true).top
    end
    room:moveCards({
      ids = table.reverse(card),
      from = player.id,
      toArea = Card.DrawPile,
      moveReason = fk.ReasonPut,
      skillName = self.name,
      proposer = player.id,
    })
    room:handleAddLoseSkills(room.current, wk_heg__zhiheng.name, nil)
  end,
}

local ceci = fk.CreateTriggerSkill{
  name = "wk_heg__ceci",
  anim_type = "special",
  events = {fk.RoundEnd},
  can_trigger = function(self, event, target, player, data)
    return player:hasSkill(self)
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    if player:getHandcardNum() < player.maxHp then
      player:drawCards(player.maxHp - player:getHandcardNum(), self.name)
    end
    local targets = table.map(table.filter(room.alive_players, function(p)
      return H.compareKingdomWith(p, player) and (p:hasSkill("wk_heg__zhiheng") or p:hasSkill("hs__zhiheng")
        or p:hasSkill("ld__lordsunquan_zhiheng") or p:hasSkill("luminous_pearl_skill")) end), Util.IdMapper)
    if #targets > 0 then
      local tos = room:askForChoosePlayers(player, targets, 1, 1, "#wk_heg__ceci-choose", self.name, false)
      local to = room:getPlayerById(tos[1])
      room:handleAddLoseSkills(to, "wk_heg__huanglong")
      local isMain = player.general == "wk_heg__sunshao" and true or false
      H.transformGeneral(room, player, isMain)
    end
  end,
}

local wk_heg__zhiheng_detach = fk.CreateTriggerSkill{
  name = "#wk_heg__zhiheng_detach",
  events = {fk.TurnStart},
  mute = true,
  can_trigger = function(self, event, target, player, data)
    return target == player and player:hasSkill("wk_heg__zhiheng", true, true)
  end,
  on_cost = Util.TrueFunc,
  on_use = function(self, event, target, player, data)
    player.room:handleAddLoseSkills(player, "-wk_heg__zhiheng", nil)
  end,
}

local huanglong = fk.CreateTriggerSkill{
  name = "wk_heg__huanglong",
  anim_type = "special",
  refresh_events = {fk.EventAcquireSkill, fk.EventLoseSkill, fk.Deathed},
  frequency = Skill.Compulsory,
  can_refresh = function(self, event, target, player, data)
    if event == fk.Deathed then
      return target:hasSkill("jiahe", true, true)
    else
      return data == self or data.name == "jiahe"
    end
  end,
  on_refresh = function(self, event, target, player, data)
    local room = player.room
    local has_jiahe = false
    local targets = table.map(table.filter(player.room.alive_players, function(p)
      return p:hasSkill("jiahe") end), Util.IdMapper)
    if #targets > 0 then has_jiahe = true end
    if player:hasSkill(self) then
      room:handleAddLoseSkills(player, has_jiahe and "-wk_heg__jiahe" or "wk_heg__jiahe", nil, false, true)
      room:handleAddLoseSkills(player, has_jiahe and "-#wk_heg__fenghuotu" or "#wk_heg__fenghuotu", nil, false, true)
      -- room:handleAddLoseSkills(player, has_jiahe and "-wk_heg__jubao" or "wk_heg__jubao", nil, false, true)
      room:setPlayerMark(player, "@@wk_heg__huanglong_skill", has_jiahe and 0 or 1)
      room:setPlayerMark(player, "@@wk_heg__huanglong_change", has_jiahe and 1 or 0)
      room.logic:trigger("fk.HuangLongDetect", nil, self.name)
    end
  end,
}

-- local wk_heg__jubao = fk.CreateTriggerSkill{
--   name = "wk_heg__jubao",
--   anim_type = "drawcard",
--   frequency = Skill.Compulsory,
--   events = {fk.EventPhaseStart},
--   can_trigger = function(self, event, target, player, data)
--     if not (target == player and player:hasSkill(self) and player.phase == Player.Finish) then return false end
--     for _, id in ipairs(player.room.discard_pile) do
--       if Fk:getCardById(id).name == "luminous_pearl" then
--         return true
--       end
--     end
--     return table.find(Fk:currentRoom().alive_players, function(p)
--       return table.find(p:getEquipments(Card.SubtypeTreasure), function(cid)
--         return Fk:getCardById(cid).name == "luminous_pearl"
--       end)
--     end)
--   end,
--   on_use = function(self, event, target, player, data)
--     local room = player.room
--     player:drawCards(1, self.name)
--     local targets = table.map(table.filter(room.alive_players, function(p)
--       return table.find(p:getEquipments(Card.SubtypeTreasure), function(cid)
--         return Fk:getCardById(cid).name == "luminous_pearl"
--       end) end), Util.IdMapper)
--     if #targets > 0 then
--       for _, pid in ipairs(targets) do
--         local p = room:getPlayerById(pid)
--         if p == player then
--           local card = room:askForCardChosen(player, p, "e", self.name)
--           room:obtainCard(player.id, card, false, fk.ReasonPrey)
--         else
--           local card = room:askForCardChosen(player, p, "he", self.name)
--           room:obtainCard(player.id, card, false, fk.ReasonPrey)
--         end
--       end
--     end
--   end,
-- }

-- local wk_heg__jubao_move = fk.CreateTriggerSkill{
--   name = "#wk_heg__jubao_move",
--   events = {fk.BeforeCardsMove},
--   frequency = Skill.Compulsory,
--   anim_type = "defensive",
--   -- main_skill = "jubao",
--   mute = true,
--   can_trigger = function(self, event, target, player, data)
--     if not player:hasSkill(self) or not (player:getEquipment(Card.SubtypeTreasure)) then return false end
--     for _, move in ipairs(data) do
--       if move.from == player.id and move.to ~= move.from and move.toArea == Card.PlayerHand then
--         for _, info in ipairs(move.moveInfo) do
--           if info.fromArea == Card.PlayerEquip and table.contains({Card.SubtypeTreasure}, Fk:getCardById(info.cardId).sub_type) then
--             return true
--           end
--         end
--       end
--     end
--   end,
--   on_use = function(self, event, target, player, data)
--     local ids = {}
--     player.room:notifySkillInvoked(player, "wk_heg__jubao", "defensive")
--     player:broadcastSkillInvoke("wk_heg__jubao")
--     for _, move in ipairs(data) do
--       if move.from == player.id and move.to ~= move.from and move.toArea == Card.PlayerHand then
--         local move_info = {}
--         for _, info in ipairs(move.moveInfo) do
--           local id = info.cardId
--           if info.fromArea == Card.PlayerEquip and table.contains({Card.SubtypeTreasure}, Fk:getCardById(id).sub_type) then
--             table.insert(ids, id)
--           else
--             table.insert(move_info, info)
--           end
--         end
--         if #ids > 0 then
--           move.moveInfo = move_info
--         end
--       end
--     end
--     if #ids > 0 then
--       player.room:sendLog{
--         type = "#cancelDismantle",
--         card = ids,
--         arg = self.name,
--       }
--     end
--   end,
-- }

local wk_heg__jiahe = fk.CreateTriggerSkill{
  name = "wk_heg__jiahe",
  anim_type = "support",
  frequency = Skill.Compulsory,
  derived_piles = "lord_fenghuo",
  can_trigger = Util.FalseFunc,
}

local wk_heg__fenghuotu = fk.CreateTriggerSkill{
  name = "#wk_heg__fenghuotu",
  anim_type = "support",
  frequency = Skill.Compulsory,
  events = {fk.EventPhaseStart, fk.Damaged},
  can_trigger = function (self, event, target, player, data)
    if event == fk.EventPhaseStart then
      return H.compareKingdomWith(player, target) and player:hasSkill(self) and #player:getPile("lord_fenghuo") > 0 and target.phase == Player.Start
    else
      return player == target and player:hasSkill(self) and data.card and #player:getPile("lord_fenghuo") > 0 and (data.card.type == Card.TypeTrick or data.card.trueName == "slash")
    end
  end,
  on_cost = function (self, event, target, player, data)
    if event == fk.EventPhaseStart then
      return true
    else
      local card = player.room:askForCard(player, 1, 1, false, self.name, false, ".|.|.|lord_fenghuo", "#ld__jiahe_damaged", "lord_fenghuo")
      if #card > 0 then
        self.cost_data = card
        return true
      end
    end
  end,
  on_use = function (self, event, target, player, data)
    local room = player.room
    if event == fk.EventPhaseStart then
      local skills = {"ld__lordsunquan_yingzi", "ld__lordsunquan_haoshi", "ld__lordsunquan_shelie", "ld__lordsunquan_duoshi"}
      local num = #player:getPile("lord_fenghuo") >= 5 and 2 or 1
      local result = room:askForCustomDialog(target, self.name,
      "packages/utility/qml/ChooseSkillBox.qml", {
        table.slice(skills, 1, #player:getPile("lord_fenghuo") + 1), 0, num, "#fenghuotu-choose:::" .. tostring(num)
      })
      if result == "" then return false end
      local choice = json.decode(result)
      if #choice > 0 then
        room:handleAddLoseSkills(target, table.concat(choice, "|"), nil, true, false)
        room.logic:getCurrentEvent():findParent(GameEvent.Turn):addCleaner(function()
          room:handleAddLoseSkills(target, '-' .. table.concat(choice, "|-"), nil, true, false)
        end)
      end
    else
      room:moveCardTo(self.cost_data, Card.DiscardPile, nil, fk.ReasonPutIntoDiscardPile, self.name, "lord_fenghuo", true, player.id)
    end
  end,

  refresh_events = {fk.EventAcquireSkill, fk.EventLoseSkill, fk.Deathed, fk.GeneralRevealed, "fk.HuangLongDetect"},
  can_refresh = function(self, event, target, player, data)
    if event ~= "fk.HuangLongDetect" and player ~= target then return false end
    if event == fk.Deathed then return player:hasSkill(self.name, true, true)
    elseif event == fk.EventAcquireSkill or event == fk.EventLoseSkill then return data == self
    else return true end
  end,
  on_refresh = function(self, event, target, player, data)
    local room = player.room
    local players = room.alive_players
    local lordsunquans = table.filter(players, function(p) return H.hasShownSkill(p, self) end)
    local jiahe_map = {}
    for _, p in ipairs(players) do
      local will_attach = false
      for _, ld in ipairs(lordsunquans) do
        if H.compareKingdomWith(ld, p) then
          will_attach = true
          break
        end
      end
      jiahe_map[p] = will_attach
    end
    for p, v in pairs(jiahe_map) do
      if v ~= p:hasSkill("wk_heg__jiahe_other&") then
        room:handleAddLoseSkills(p, v and "wk_heg__jiahe_other&" or "-wk_heg__jiahe_other&", nil, false, true)
      end
    end
  end,
}

local wk_heg__jiaheOther = fk.CreateActiveSkill{
  name = "wk_heg__jiahe_other&",
  prompt = function()
    local targets = table.map(table.filter(Fk:currentRoom().alive_players, function(p)
      return p:getMark("@@wk_heg__huanglong_skill") ~= 0 end), Util.IdMapper)
    return "#ld__jiahe_other:" .. targets[1]
  end,
  can_use = function(self, player)
    local room = Fk:currentRoom()
    local targets = table.map(table.filter(room.alive_players, function(p)
      return p:getMark("@@wk_heg__huanglong_skill") ~= 0 end), Util.IdMapper)
    local target = room:getPlayerById(targets[1])
    return player:usedSkillTimes(self.name, Player.HistoryPhase) == 0 and target and target:hasSkill("wk_heg__jiahe")
  end,
  card_num = 1,
  card_filter = function(self, to_select, selected)
    return #selected < 1 and Fk:getCardById(to_select).type == Card.TypeEquip
  end,
  target_num = 0,
  on_use = function(self, room, effect)
    local targets = table.map(table.filter(room.alive_players, function(p)
      return p:getMark("@@wk_heg__huanglong_skill") ~= 0 end), Util.IdMapper)
    local target = room:getPlayerById(targets[1])
    if target and target:hasSkill("wk_heg__jiahe") then
      target:addToPile("lord_fenghuo", effect.cards, true, self.name)
    end
  end,
}

sunshao:addSkill(bizheng)
sunshao:addSkill(ceci)

-- wk_heg__jubao:addRelatedSkill(wk_heg__jubao_move)
wk_heg__zhiheng:addRelatedSkill(wk_heg__zhiheng_detach)
sunshao:addRelatedSkill(wk_heg__zhiheng)
sunshao:addRelatedSkill(huanglong)

sunshao:addRelatedSkill(wk_heg__jiahe)
-- sunshao:addRelatedSkill(wk_heg__jubao)
Fk:addSkill(wk_heg__fenghuotu)
Fk:addSkill(wk_heg__jiaheOther)

Fk:loadTranslationTable{
  ["wk_heg__sunshao"] = "孙邵",
  ["#wk_heg__sunshao"] = "创基扶政",
  ["designer:wk_heg__sunshao"] = "教父&祭祀&二四&边缘&风箫",
  
  ["wk_heg__bizheng"] = "弼政",
  [":wk_heg__bizheng"] = "每回合限一次，当前回合角色的牌于出牌阶段内因弃置而置入弃牌堆后，你可获得之并将X张牌置于牌堆顶，然后其获得〖制衡〗直至其回合开始。（X为其已明置武将牌上技能数）",
  ["wk_heg__ceci"] = "册辞",
  [":wk_heg__ceci"] = "每轮结束时，你可将手牌摸至体力上限，然后若存在与你势力相同且拥有〖制衡〗的角色，其获得〖黄龙〗，你变更此武将牌。",

  ["wk_heg__huanglong"] = "黄龙",
  -- [":wk_heg__huanglong"] = "锁定技，若存在拥有〖嘉禾〗的角色，你令其失去〖烽火〗的条件删去“受到锦囊牌造成的伤害后”，否则你视为拥有〖嘉禾〗和〖聚宝〗。",
  [":wk_heg__huanglong"] = "锁定技，若存在拥有〖嘉禾〗的角色，你令其失去〖烽火〗的条件删去“受到锦囊牌造成的伤害后”，否则你视为拥有〖嘉禾〗。",

  ["#wk_heg__ceci-choose"] = "册辞：选择一名与你势力相同且拥有〖制衡〗的角色，其获得〖黄龙〗",

  ["wk_heg__zhiheng"] = "制衡",
  [":wk_heg__zhiheng"] = "出牌阶段限一次，你可弃置至多X张牌（X为你的体力上限），摸等量的牌。<font color='grey'><small>此为〖制衡（弼政）〗</small></font>",
  ["@@wk_heg__huanglong_skill"] = "黄龙 拥有技能",
  ["@@wk_heg__huanglong_change"] = "黄龙 加强技能",

  ["wk_heg__jiahe"] = "嘉禾",
  [":wk_heg__jiahe"] = "<b><font color='goldenrod'>君主技</font></b>，你拥有“缘江烽火图”。<br>" ..
  "#<b>缘江烽火图</b>：①吴势力角色出牌阶段限一次，其可将一张装备牌置于“缘江烽火图”上，称为“烽火”。<br>" ..
  "②吴势力角色的准备阶段，其可根据“烽火”数量选择获得对应的技能直至其回合结束：<br>"..
  "不小于一，〖英姿〗；不小于二，〖好施〗；不小于三，〖涉猎〗；不小于四，〖度势〗；不小于五，可额外选择一项。<br>"..
  "③锁定技，当你受到【杀】或锦囊牌造成的伤害后，你将一张“烽火”置入弃牌堆。",
  ["wk_heg__jiahe_other&"] = "烽火图",
  [":wk_heg__jiahe_other&"] = "①出牌阶段限一次，你可将一张装备牌置于“缘江烽火图”上，称为“烽火”。<br>" ..
  "②准备阶段，你可根据“烽火”数量选择获得对应的技能直至其回合结束：<br>"..
  "不小于一，〖英姿〗；不小于二，〖好施〗；不小于三，〖涉猎〗；不小于四，〖度势〗；不小于五，可额外选择一项。",

  -- ["#wk_heg__jubao_move"] = "聚宝",
  -- ["wk_heg__jubao"] = "聚宝",
  -- [":wk_heg__jubao"] = "锁定技，①结束阶段，若弃牌堆或场上存在【定澜夜明珠】，你摸一张牌，然后获得拥有【定澜夜明珠】的角色的一张牌；②其他角色获得你装备区内的宝物牌时，取消之。",

  ["#wk_heg__fenghuotu"] = "烽火图",

  ["$wk_heg__bizheng1"] = "弼亮四世，正色率下。",
  ["$wk_heg__bizheng2"] = "弼佐辅君，国事正法。",
  ["$wk_heg__ceci1"] = "无传书卷记，功过自有评",
  ["$wk_heg__ceci2"] = "佚以典传，千秋谁记？",
  ["~wk_heg__sunshao"] = "此去一别，难见文举…",
}

local guanning = General(extension, "wk_heg__guanning", "qun", 3, 3, General.Male)
local duanyi = fk.CreateTriggerSkill{
  name = "wk_heg__duanyi",
  events = {fk.GeneralRevealed},
  anim_type = "special",
  can_trigger = function(self, event, target, player, data)
    if player:hasSkill(self) then
      for _, v in pairs(data) do
        -- 先这样，藕合过于麻烦
        if table.contains(Fk.generals[v]:getSkillNameList(), self.name) 
         or (player:getMark("wk_heg__duanyi") ~= 0 and target ~= player and not target.dead
          and not ((player:getMark("wk_heg__duanyi") == 9 and target.phase == 9) or (player:getMark("wk_heg__duanyi") ~= 9 and target.phase ~= 9))) then 
          return true 
        end
      end
    end
  end,
  on_cost = Util.TrueFunc,
  on_use = function (self, event, target, player, data)
    local room = player.room
    if player:getMark("wk_heg__duanyi") == 0 then
      player:drawCards(2, self.name)
      player.room:setPlayerMark(player, "wk_heg__duanyi", player.phase)
    else
      local choices = {"wk_heg__duanyi_discard::"..target.id, "Cancel"}
      local choice = room:askForChoice(player, choices, self.name)
      if choice ~= "Cancel" then
        room:askForDiscard(target, 2, 2, true, self.name, false)
      end
    end
  end,
}

---@param object Card|Player
---@param markname string
---@param suffixes string[]
---@return boolean
local function hasMark(object, markname, suffixes)
  if not object then return false end
  for mark, _ in pairs(object.mark) do
    if mark == markname then return true end
    if mark:startsWith(markname .. "-") then
      for _, suffix in ipairs(suffixes) do
        if mark:find(suffix, 1, true) then return true end
      end
    end
  end
  return false
end

local gaojie = fk.CreateTriggerSkill{
  name = "wk_heg__gaojie",
  events = {fk.TargetConfirming, fk.AfterCardsMove},
  anim_type = "defensive",
  frequency = Skill.Compulsory,
  can_trigger = function (self, event, target, player, data)
    if not player:hasSkill(self) then return false end
    if event == fk.TargetConfirming then
      return target == player and data.card and data.card:isCommonTrick() and data.card.package.name == "strategic_advantage"
    else
      local cardInfo = {}
      for _, move in ipairs(data) do
        if move.to and move.to == player.id and move.toArea == Card.PlayerHand then
          for _, info in ipairs(move.moveInfo) do
            if hasMark(Fk:getCardById(info.cardId), "@@alliance", MarkEnum.CardTempMarkSuffix) then
              table.insert(cardInfo, info.cardId)
            end
          end
        end
      end
      if #cardInfo > 0 then
        self.cost_data = cardInfo
        return true
      end
    end
  end,
  on_cost = Util.TrueFunc,
  on_use = function (self, event, target, player, data)
    if event == fk.TargetConfirming then
      AimGroup:cancelTarget(data, player.id)
      return true
    else
      if #self.cost_data > 0 then
        player.room:throwCard(self.cost_data, self.name, player, player)
        if player:isWounded() and not player.dead then
          player.room:recover({
            who = player,
            num = 1,
            recoverBy = player,
            skillName = self.name,
          })
        end
      end
    end
  end,
}

guanning:addSkill(duanyi)
guanning:addSkill(gaojie)
Fk:loadTranslationTable{
  ["wk_heg__guanning"] = "管宁",
  ["#wk_heg__guanning"] = "辟境归元",
  ["designer:wk_heg__guanning"] = "教父&猪",

  ["wk_heg__duanyi"] = "断义",
  [":wk_heg__duanyi"] = "当你首次明置此武将牌后，你摸两张牌，且其他角色明置武将牌后，若其明置武将牌的方式与你首次明置武将牌的方式不同，你可令其弃置两张牌。<br />"..
  "<font color = 'gray'>注：明置武将牌的方式，分为“回合开始时亮将”和“因技能亮将”两种形式。</font>",
  ["wk_heg__gaojie"] = "高节",
  [":wk_heg__gaojie"] = "锁定技，当你成为势备篇锦囊牌的目标时，取消之；当你获得带有“合纵”标记的牌后，你弃置之，然后回复1点体力。<br />"..
  "<font color = 'gray'>注：势备篇锦囊牌包括【勠力同心】【联军盛宴】【挟天子以令诸侯】【敕令】【调虎离山】【水淹七军】【火烧连营】。</font>",

  ["wk_heg__duanyi_discard"] = "令 %dest 弃置两张牌",

  ["$wk_heg__duanyi1"] = "尔之于我若无，我之于世若虚。",
  ["$wk_heg__duanyi2"] = "借剑断席，天下无人同我。",
  ["$wk_heg__gaojie1"] = "失路青山隐，藏名白水游。",
  ["$wk_heg__gaojie2"] = "隐居青松畔，遁走孤竹丘。",
  ["~wk_heg__guanning"] = "高节始终，无憾矣…",
}

local jvshou = General(extension, "wk_heg__jvshou", "qun", 3)

local tugui = fk.CreateTriggerSkill{
  name = "wk_heg__tugui",
  anim_type = "defensive",
  events = {fk.AfterCardsMove, fk.EnterDying, fk.EventPhaseEnd},
  can_trigger = function (self, event, target, player, data)
    local ret = false
    if event == fk.AfterCardsMove then
      if not player:hasSkill(self) or not player:isKongcheng() then return end
      for _, move in ipairs(data) do
        if move.from == player.id then
          for _, info in ipairs(move.moveInfo) do
            if info.fromArea == Card.PlayerHand and player:usedSkillTimes(self.name, Player.HistoryTurn) == 0 then
              ret = true
              break
            end
          end
        end
      end
      if ret then
        return table.find(player.room.alive_players, function(p) return player:distanceTo(p) == 1 and not p:isKongcheng() end)
      end
    elseif event == fk.EnterDying then
      if player == target and player:hasSkill(self) and player:usedSkillTimes(self.name, Player.HistoryTurn) == 0 then
        ret = true
      end
      if ret then
        return table.find(player.room.alive_players, function(p) return player:distanceTo(p) == 1 and not p:isKongcheng() end)
      end
    else
      return player:hasSkill(self) and player == target and player.phase == Player.Play and player:getMark("wk_heg__tugui") ~= 0 
    end
  end,
  on_cost = function (self, event, target, player, data)
    if event == fk.AfterCardsMove or event == fk.EnterDying then
      return player.room:askForSkillInvoke(player, self.name, nil, "#wk_heg__tugui-ask")
    else
      return true
    end
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    if event == fk.AfterCardsMove or event == fk.EnterDying then
      local targets = table.map(table.filter(room.alive_players, function(p) return player:distanceTo(p) == 1 and not p:isKongcheng() end), Util.IdMapper)
      if #targets > 0 then
        local to = room:askForChoosePlayers(player, targets, 1, 1, "#wk_heg__tugui-choose", self.name, false)
        local card = room:askForCardChosen(player, room:getPlayerById(to[1]), "h", self.name)
        room:obtainCard(player.id, card, false, fk.ReasonPrey)
        player:showCards(card)
        local mark = player:getTableMark("wk_heg__tugui")
        table.insertIfNeed(mark, {player.id, card})
        -- local mark = U.getMark(player, "wk_heg__tugui")
        -- table.insert(mark, {player.id, card})
        room:setPlayerMark(player, "wk_heg__tugui", mark)
      end
    else
      for _, t in ipairs(player:getMark("wk_heg__tugui")) do
        local p = player.room:getPlayerById(t[1])
        if p and table.contains(p:getCardIds("he"), t[2]) then
          H.removeGeneral(room, player, player.deputyGeneral == "wk_heg__jvshou")
          break
        end
      end
      room:setPlayerMark(player, "wk_heg__tugui", 0)
    end
  end,
}

local yingshou = fk.CreateTriggerSkill{
  name = "wk_heg__yingshou",
  anim_type = "drawcard",
  events = {fk.EventPhaseStart},
  can_trigger = function (self, event, target, player, data)
    return player == target and player.phase == Player.Finish and player:hasSkill(self)
  end,
  on_use = function (self, event, target, player, data)
    local room = player.room
    local targets = table.map(table.filter(room.alive_players, function(p) return H.compareKingdomWith(player, p) end), Util.IdMapper)
    local tos = room:askForChoosePlayers(player, targets, 1, 1, "#wk_heg__yingshou-choose")
    if #tos > 0 then
      local to = room:getPlayerById(tos[1])
      to:drawCards(2, self.name)
      room:setPlayerMark(to, "@@wk_heg__yingshou", 1)
    end
  end,
}

local yingshou_delay = fk.CreateTriggerSkill{
  name = "#wk_heg__yingshou_delay",
  anim_type = "special",
  events = {fk.Damage},
  can_trigger = function (self, event, target, player, data)
    return data.from:getMark("@@wk_heg__yingshou") > 0 and not data.from:isNude() and data.from.phase == Player.Play and player:hasSkill(self)
  end,
  on_cost = Util.TrueFunc,
  on_use = function (self, event, target, player, data)
    player.room:askForDiscard(data.from, 1, 1, true, self.name, false)
  end,

  refresh_events = {fk.EventPhaseEnd},
  can_refresh = function (self, event, target, player, data)
    return target:getMark("@@wk_heg__yingshou") > 0 and target.phase == Player.Play
  end,
  on_refresh = function (self, event, target, player, data)
    player.room:setPlayerMark(target, "@@wk_heg__yingshou", 0)
  end,
}

yingshou:addRelatedSkill(yingshou_delay)
jvshou:addSkill(tugui)
jvshou:addSkill(yingshou)

Fk:loadTranslationTable{
  ["wk_heg__jvshou"] = "沮授",
  ["#wk_heg__jvshou"] = "志北挽魂",
  ["designer:wk_heg__jvshou"] = "教父&小曹神",

  ["wk_heg__tugui"] = "图归",
  [":wk_heg__tugui"] = "①每回合限一次，当你失去最后的手牌后或当你进入濒死状态后，你可获得与你距离为1的其他角色的一张手牌并展示之；②出牌阶段结束时，若你未失去以此法获得的所有牌，你移除此武将牌。",
  ["wk_heg__yingshou"] = "营守",
  [":wk_heg__yingshou"] = "结束阶段，你可令一名与你势力相同的角色摸两张牌，若如此做，当其于下个出牌阶段内造成伤害后，其弃置一张牌。",

  ["#wk_heg__tugui-ask"] = "图归：是否获得与你距离为1的其他角色的一张手牌",
  ["#wk_heg__tugui-choose"] = "图归：选择一名与你距离为1的其他角色",

  ["#wk_heg__yingshou_delay"] = "营守",
  ["#wk_heg__yingshou-choose"] = "营守：选择一名与你势力相同的角色",
  ["@@wk_heg__yingshou"] = "营守",

  ["$wk_heg__tugui1"] = "矢志于北，尽忠于国。",
  ["$wk_heg__tugui2"] = "命系袁氏，一心向北。",
  ["$wk_heg__yingshou1"] = "由缓至急，循循而进。",
  ["$wk_heg__yingshou2"] = "事须缓图，欲速不达也。",
  ["~wk_heg__jvshou"] = "身处河南，魂归河北…",
}
local kuaizi = General(extension, "wk_heg__kuaizi", "qun", 3, 3, General.Male)
local zongpo = fk.CreateTriggerSkill{
  name = "wk_heg__zongpo",
  events = {fk.CardUseFinished},
  anim_type = "offensive",
  can_trigger = function(self, event, target, player, data)
    return target == player and player:hasSkill(self) and player.room.current ~= player and player:usedSkillTimes(self.name, Player.HistoryTurn) == 0
  end,
  on_cost = function(self, event, target, player, data)
    local room = player.room
    local targets = table.map(table.filter(room.alive_players, function (p) return player:distanceTo(p) == 1 end), Util.IdMapper)
    local tos, id = room:askForChooseCardAndPlayers(player, targets, 1, 1, ".|.|.|.|.|basic", "#wk_heg__zongpo-choose", self.name, true)
    if #tos ~= 0 then
      self.cost_data = {tos, id}
      return true
    end
  end,
  on_use = function (self, event, target, player, data)
    local room = player.room
    local tos = self.cost_data[1]
    local to = room:getPlayerById(tos[1])
    room:obtainCard(tos[1], self.cost_data[2], false, fk.ReasonGive)

    local mark = {}
    table.insert(mark, self.cost_data[2])
    room:setCardMark(Fk:getCardById(self.cost_data[2]), "@@alliance-inhand", 1)
    room:setPlayerMark(to, "wk_heg__zongpo", mark)

    if player.dead or to.dead then return false end
    local choices = {"wk_heg__zongpo_giveback:".. player.id, "Cancel"}
    local choice = room:askForChoice(to, choices, self.name)
    local card_ids = Card:getIdList(data.card)
    if #card_ids == 0 or choice == "Cancel" then return false end
    if data.card.type == Card.TypeEquip then
      if not table.every(card_ids, function (id)
        return room:getCardArea(id) == Card.PlayerEquip and room:getCardOwner(id) == player
      end) then return false end
    else
      if not table.every(card_ids, function (id)
        return room:getCardArea(id) == Card.Processing
      end) then return false end
    end
    room:moveCardTo(card_ids, Player.Hand, player, fk.ReasonPrey, self.name, nil, false, player.id)
  end,

  refresh_events = {fk.AfterCardsMove},
  can_refresh = function(self, event, target, player, data)
    local room = player.room
    local toLose = {}
    for _, move in ipairs(data) do
      if not move.from then return false end
      local to = room:getPlayerById(move.from)
      if to.dead or type(to:getMark("wk_heg__zongpo")) ~= "table" then return false end
      local mark = to:getMark("wk_heg__zongpo")
      for _, info in ipairs(move.moveInfo) do
        if info.fromArea == Card.PlayerHand and table.contains(mark, info.cardId) then
          table.insert(toLose, info.cardId)
        end
      end
    end
    if #toLose > 0 then
      self.cost_data = toLose
      return true
    end
  end,
  on_refresh = function(self, event, target, player, data)
    local room = player.room
    for _, move in ipairs(data) do
      local to = room:getPlayerById(move.from)
      local mark = to:getMark("wk_heg__zongpo")
      table.forEach(self.cost_data, function(id) table.removeOne(mark, id) end)
      table.forEach(self.cost_data, function(id) player.room:setCardMark(Fk:getCardById(id), "@@alliance-inhand", 0) end)
      player.room:setPlayerMark(to, "wk_heg__zongpo", #mark > 0 and mark or 0)
    end
  end,
}

local shenshi = fk.CreateTriggerSkill{
  name = "wk_heg__shenshi",
  anim_type = "defensive",
  events = {fk.AfterCardsMove},
  can_trigger = function(self, event, target, player, data)
    local room = player.room
    if not player:hasSkill(self) then return false end
    for _, move in ipairs(data) do
      if move.from and move.from == player.id and move.to and move.to ~= player.id and move.toArea == Card.PlayerHand then
        for _, info in ipairs(move.moveInfo) do
          if info.fromArea == Card.PlayerHand or info.fromArea == Card.PlayerEquip then
            self.cost_data = move.to
            local from = room:getPlayerById(move.from)
            local to = room:getPlayerById(move.to)
            return not H.compareKingdomWith(from, to)
            -- return H.isBigKingdomPlayer(to)
          end
        end
      end
    end
  end,
  on_use = function (self, event, target, player, data)
    local room = player.room
    local to = room:getPlayerById(self.cost_data)
    to:drawCards(1, self.name)
    room:setPlayerMark(to, "wk_heg__shenshi_draw-turn", 1)
  end,

  refresh_events = {fk.DamageCaused},
  can_refresh = function(self, event, target, player, data)
    return data.from and data.from:getMark("wk_heg__shenshi_draw-turn") > 0 and H.compareKingdomWith(data.to, player)
  end,
  on_refresh = function (self, event, target, player, data)
    player.room:setPlayerMark(player, "wk_heg__shenshi_damage-turn", 1)
  end,
}

local shenshi_delay = fk.CreateTriggerSkill{
  name = "#wk_heg__shenshi_delay",
  mute = true,
  events = {fk.TurnEnd},
  can_trigger = function (self, event, target, player, data)
    return player:usedSkillTimes(shenshi.name, Player.HistoryTurn) > 0
  end,
  on_cost = Util.TrueFunc,
  on_use = function (self, event, target, player, data)
    local room = player.room
    if player:getMark("wk_heg__shenshi_damage-turn") == 0 then
      local targets = table.map(table.filter(room.alive_players, function(p) return H.compareKingdomWith(p, player) end), Util.IdMapper)
      room:sortPlayersByAction(targets)
      for _, pid in ipairs(targets) do
        local p = room:getPlayerById(pid)
        if not p.dead then
          p:drawCards(1, self.name)
        end
      end
    end
  end,
}
shenshi:addRelatedSkill(shenshi_delay)
kuaizi:addSkill(zongpo)
kuaizi:addSkill(shenshi)

Fk:loadTranslationTable{
  ["wk_heg__kuaizi"] = "蒯越蒯良",
  ["#wk_heg__kuaizi"] = "雍论臼谋",
  ["designer:wk_heg__kuaizi"] = "教父&风箫",

  ["wk_heg__zongpo"] = "纵迫",
  [":wk_heg__zongpo"] = "每回合限一次，当你于回合外使用牌结算后，你可交给一名你计算距离为1的角色一张基本牌，此牌于其手牌区内视为拥有“合纵”标记，然后其可令你获得你使用的牌。",
  ["wk_heg__shenshi"] = "审时",
  [":wk_heg__shenshi"] = "其他势力角色获得你的牌后，你可令其摸一张牌，若如此做，此回合结束时，若此回合内所有以此法摸牌的角色于以此法摸牌后未对与你势力相同的角色造成过伤害，与你势力相同的角色各摸一张牌。",

  ["#wk_heg__zongpo-choose"] = "纵迫：你可以交给一名你计算距离为1的角色一张基本牌",
  ["wk_heg__zongpo_giveback"] = "令 %src 获得其使用的牌",

  ["#wk_heg__shenshi_delay"] = "审时",

  ["$wk_heg__zongpo1"] = "得遇曹公，吾之幸也。",
  ["$wk_heg__zongpo2"] = "曹公得荆不喜，喜得吾二人足以。",
  ["$wk_heg__shenshi1"] = "深中足智，鉴时审情。",
  ["$wk_heg__shenshi2"] = "数语之言，审时度势。",
  ["~wk_heg__kuaizi"] = "表不能善用，所憾也",
}

return extension